using UnityEngine;
using System.Collections;

public class CubeSpawner : MonoBehaviour 
{
    public GameObject CubeInstance;
    public Vector3 CenterPosition;
    public Vector3 FrameDimension;
    public Vector3 CubeDistance;

    private ArrayList CubeList;
    private bool IsFrameRotating;
    private Vector3 RotationAxis;
    private Vector3 RotationPosition;
    private bool RotationDirection;
	// Use this for initialization
	void Start () 
    {
        Vector3 LocalPos;
        CubeList = new ArrayList();

        for ( int iX = 0; iX < FrameDimension.x; ++iX )
        {
            LocalPos.x = CubeDistance.x * ( iX - FrameDimension.x / 2 + 0.5f );
            for ( int iY = 0; iY < FrameDimension.y; ++iY )
            {
                LocalPos.y = CubeDistance.y * ( iY - FrameDimension.y / 2 + 0.5f );
                for ( int iZ = 0; iZ < FrameDimension.z; ++iZ )
                {
                    LocalPos.z = CubeDistance.z * ( iZ - FrameDimension.z / 2 + 0.5f );
                    GameObject instance = Instantiate( CubeInstance, LocalPos + CenterPosition, Quaternion.Euler( 0, 0, 0 ) ) as GameObject;
                    Cube cube = instance.GetComponent<Cube>();
                    cube.FrameCenter = CenterPosition;

                    CubeList.Add( cube );
                }
            }
        }

        IsFrameRotating = false;
	}

    // Update is called once per frame
    void Update() 
    {
        // test: use key to S and F to control the frame rotation
        bool IsKeyFDown = Input.GetKeyDown( KeyCode.F );
        bool IsKeySDown = Input.GetKeyDown( KeyCode.S );

        if ( IsKeyFDown )
        {
            // do a horizontal rotation based on one layer below the center
            StartFrameRotation( new Vector3( 1.0f, 0, 0 ), CenterPosition - new Vector3( 0, CubeDistance.y, 0 ), true );
        }
        else if ( IsKeySDown )
        {
            StartFrameRotation( new Vector3( 0, 1.0f, 0 ), CenterPosition - new Vector3( 0, CubeDistance.y, 0 ), true );
        }
        else
        {
            // not implemented
        }
        // test finished


        if ( IsFrameRotating )
        {
            FrameRotation();
        }
	}

    // update every frame with rotation
    void FrameRotation()
    {
        uint nStoppedNum = 0;
        for ( int i = 0; i < CubeList.Count; ++i )
        {
            Cube cube = CubeList[ i ] as Cube;
            if ( !cube.CubeRotation( RotationAxis, RotationDirection ) )
            {
                nStoppedNum++;
            }
            
        }
        if ( nStoppedNum == CubeList.Count )
        {
            IsFrameRotating = false;
        }
    }

    // interface: call to start the frame rotation 90 degrees
    // Input:   
    //      vAxis: which axis to rotate
    //      vPos: which world position the action ( sliding ) started in
    //      bDirection: which direction Clockwise or Counter Clockwise
    public void StartFrameRotation( Vector3 vAxis, Vector3 vPos, bool bDirection )
    {
        if ( !IsFrameRotating )
        {
            IsFrameRotating = true;
            RotationAxis = vAxis;
            RotationPosition = vPos;
            RotationDirection = bDirection;
            for ( int i = 0; i < CubeList.Count; ++i )
            {
                Cube cube = CubeList[ i ] as Cube;
                bool isQualifiedCube = ( Mathf.Abs( Vector3.Dot( vAxis, cube.transform.position - vPos ) ) < Vector3.Dot( vAxis, cube.transform.localScale ) );
                if ( ( !cube.GetCubeRotationStatus() ) && isQualifiedCube )
                {
                    cube.SetCubeRotationStart();
                }
            }
        }
    }

}
